﻿using System;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml;
using Library.Logging;
using System.IO;
using NguyenHoa.Domains;
using NguyenHoa.Services;
using System.Reflection;

namespace NguyenHoa.Web.App_Code
{
  public class BasePage : Page
  {
    private XmlDataSource m_xmlData;

    #region URL SEO Link
    [Serializable]
    public enum RewriteUrlList
    {
      [LinkSEOAttribute(@"~/trang-chu.aspx")]
      [OriginalLink(@"~/Default.aspx")]
      Default = 1,

      [LinkSEOAttribute(@"~/trang-home.aspx")]
      [OriginalLink(@"~/Pages/home.aspx")]
      Home
    }
    #endregion

    #region Override Base

    protected override void OnError(EventArgs e)
    {
      Exception ex = Server.GetLastError();
      Logger.LogError("BasePage::OnError.", ex, DefaultLoggingCategory, null);
    }

    protected override void OnLoad(EventArgs e)
    {
      // Intentionally pauses server-side processing, to demonstrate the Loading Panel functionality.
      if (IsCallback)
        System.Threading.Thread.Sleep(500);

      base.OnLoad(e);
    }

    protected override void OnInit(EventArgs e)
    {
      string curUrl = Request.Url.AbsoluteUri.ToLower();
      base.OnInit(e);
    }

    protected void Page_PreInit(object sender, EventArgs e)
    {
      string themeName = GlobalCache.Instance.Themes;
      this.Theme = themeName;
    }

    protected override void InitializeCulture()
    {
      base.InitializeCulture();
      LoadLanguage(CurrentLanguage);
    }
    #endregion

    #region Properties
    internal Language CurrentLanguage
    {
      set { Session["PageLanguage"] = value; }
      get
      {
        if (Session["PageLanguage"] == null)
          Session["PageLanguage"] = new LanguageService().GetById(GlobalCache.Instance.DefaultLanguage);
        return (Language)Session["PageLanguage"];
      }
    }

    internal string ErrorMessage
    {
      get { return Session["PageErrorMessage"] as string; }
      set { Session["PageErrorMessage"] = value; }
    }

    public string SelectedTopMenu
    {
      get
      {
        string groupId = "0";
        if (Session["PageSelectedMenuGroup"] != null)
        {
          groupId = Session["PageSelectedMenuGroup"].ToString();
        }
        return groupId;
      }
      set
      {
        Session["PageSelectedMenuGroup"] = value;
      }
    }

    public string SelectedMenuItem
    {
      get
      {
        string itemId = "";
        if (Session["PageSelectedMenuItem"] == null)
          Session["PageSelectedMenuItem"] = TypeId;

        itemId = Session["PageSelectedMenuItem"] as string;
        return itemId;
      }
      set
      {
        Session["PageSelectedMenuItem"] = value;
      }
    }

    public string SelectedMenuItemTitle
    {
      get
      {
        string itemId = "";
        if (Session["PageSelectedMenuItemTitle"] == null)
          Session["PageSelectedMenuItemTitle"] = "";

        itemId = Session["PageSelectedMenuItemTitle"].ToString();
        return itemId;
      }
      set
      {
        Session["PageSelectedMenuItemTitle"] = value;
      }
    }

    public string SelectedSubMenuItem
    {
      set
      {
        Session["PageSelectedSubMenuItem"] = value;
      }
      get
      {
        if (Session["PageSelectedSubMenuItem"] == null)
        {
          return null;
        }
        return (string)Session["PageSelectedSubMenuItem"];
      }
    }

    public string SelectedSubMenuItemTitle
    {
      set
      {
        Session["PageSubSelectedMenuItemTitle"] = value;
      }
      get
      {
        if (Session["PageSubSelectedMenuItemTitle"] == null)
        {
          return null;
        }
        return (string)Session["PageSubSelectedMenuItemTitle"];
      }
    }


    public string LocalPath
    {
      get { return Server.MapPath("~/" + PostedDirectory + "/"); }
    }

    public string PostedDirectory
    {
      get { return m_postedDirectory; }
      set { m_postedDirectory = value; }
    }

    private string m_postedDirectory = "App_Temp";

    public const string DefaultLoggingCategory = "General";

    public string XmlStatusFile
    {
      get
      {
        string culture = (!string.IsNullOrEmpty(CurrentLanguage.Culture)) ? "." + CurrentLanguage.Culture : "";
        return "~/App_Data/Status" + culture + ".xml";
      }
    }

    public string XmlMenuFile
    {
      get
      {
        string culture = (!string.IsNullOrEmpty(CurrentLanguage.Culture)) ? "." + CurrentLanguage.Culture : "";
        return "~/App_Data/PageMenu" + culture + ".xml";
      }
    }

    public int? TypeId
    {
      get
      {
        string tid = Request.QueryString["tid"];
        if (String.IsNullOrEmpty(tid)) return null;
        return int.Parse(tid);
      }
    }

    public int Id
    {
      get
      {
        int id;
        int.TryParse(Request.QueryString["id"], out id);
        return id;
      }
    }
    #endregion

    #region Need To Override
    protected virtual void ApplyAction()
    { }

    public XmlDataSource XmlData
    {
      get { return m_xmlData; }
      set { m_xmlData = value; }
    }

    internal virtual string PageTitle
    {
      get { return ""; }
    }

    #endregion

    #region Private Methods
    private void LoadLanguage(Language lang)
    {
      CurrentLanguage = lang;
      Page.Culture = CurrentLanguage.Culture;
      Page.UICulture = CurrentLanguage.Culture;
    }

    #endregion

    #region Public Methods

    public static string GetSEOLink(object value)
    {
      bool isRewrite = GlobalCache.Instance.RewriteOn;
      string retVal = string.Empty;
      try
      {
        FieldInfo fieldInfo = value.GetType().GetField(value.ToString());

        if (isRewrite)
        {
          LinkSEOAttribute[] attributes = (LinkSEOAttribute[])fieldInfo.GetCustomAttributes(typeof(LinkSEOAttribute), false);
          retVal = ((attributes.Length > 0) ? attributes[0].Text : value.ToString());
        }
        else
        {
          OriginalLink[] attributes = (OriginalLink[])fieldInfo.GetCustomAttributes(typeof(OriginalLink), false);
          retVal = ((attributes.Length > 0) ? attributes[0].Text : value.ToString());
        }
      }

      catch (Exception ex)
      {
        Logger.LogError("GetAttributeDescription", ex, "General", null);
      }
      return retVal;
    }

    public void CreateAuthenticationTicket(string username)
    {
      FormsAuthentication.SetAuthCookie(username, false);
      FormsAuthenticationTicket clientTicket =
      new FormsAuthenticationTicket(1,
                                      username,
                                      DateTime.Now,
                                      DateTime.Now.AddMinutes(Session.Timeout + 1),
                                      false,
                                      "Agent");
      HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(clientTicket));
      Response.Cookies.Add(cookie);
    }

    public void ClearAuthenticationTicket()
    {
      FormsAuthentication.SignOut();
      Session.Clear();
    }

    public void WriteLog(string description, Exception ex)
    {
      Logger.LogError(description, ex, DefaultLoggingCategory, null);
    }

    public string CreateDir(string configPath, out string relativePath)
    {
      relativePath = string.Empty;
      try
      {
        string directory = configPath + DateTime.Now.Day.ToString() + DateTime.Now.Month.ToString() + DateTime.Now.Year.ToString() + "/";
        string absolutePath = "~/" + directory;
        absolutePath = Server.MapPath(absolutePath);
        if (!Directory.Exists(absolutePath))
        {
          Directory.CreateDirectory(absolutePath);
        }
        relativePath = "../" + directory;
        return absolutePath;
      }
      catch (Exception ex)
      {
        WriteLog("Create New Directory", ex);
        return string.Empty;
      }
    }

    public XmlDataSource GetXmlDataSource(string vnDataFile, string usDataFile, string xmlPath)
    {
      XmlDataSource dsData = new XmlDataSource();
      if (CurrentLanguage.Id == (int)LanguageList.Vietnamese)
        dsData.DataFile = vnDataFile;
      else if (CurrentLanguage.Id == (int)LanguageList.English)
        dsData.DataFile = usDataFile;
      dsData.XPath = xmlPath;
      return dsData;
    }

    public string GetItemDescription(object status, string path)
    {
      XmlDataSource dsData = new XmlDataSource();
      dsData.DataFile = XmlStatusFile;
      dsData.XPath = path;

      XmlNode node = dsData.GetXmlDocument().SelectSingleNode(path + "[@Id='" + status + "']");
      if (node != null)
        return node.Attributes["Value"].Value;
      return "";
    }

    public void SetPageLanguage(Language lang)
    {
      LoadLanguage(lang);
      Response.Redirect(Request.Url.AbsoluteUri);
    }

    public string GetPageWithTypeId(string page)
    {
      XmlDocument doc = new XmlDocument();
      try
      {
        doc.Load(MapPath(XmlMenuFile));
        if (doc.ChildNodes.Count > 1)
        {
          XmlNode root = doc.ChildNodes[1];
          foreach (XmlNode node in root)
          {
            if (node.NodeType == XmlNodeType.Element)
            {
              string url = string.Empty;
              if (node.Attributes["NavigateUrl"] != null)
              {
                url = node.Attributes["NavigateUrl"].ToString();
                if (!string.IsNullOrEmpty(url) && page.ToLower().Contains(url.ToLower()))
                  page = url;
                break;
              }
              if (node.ChildNodes.Count > 0)
              {
                for (int i = 0; i < node.ChildNodes.Count; i++)
                {
                  XmlNode subNode = node.ChildNodes[i];
                  if (subNode.NodeType == XmlNodeType.Element && node.Attributes["NavigateUrl"] != null)
                  {
                    url = node.Attributes["NavigateUrl"].ToString();
                    if (!string.IsNullOrEmpty(url) && page.ToLower().Contains(url.ToLower()))
                      page = url;
                    break;
                  }
                }
              }
            }
          }
        }
      }
      catch (Exception ex)
      {
        WriteLog("PageMenu.ascx::Show Menu", ex);
      }
      return page;
    }

    public Control GetPostBackControl()
    {
      Control control = null;

      string ctrlname = this.Request.Params.Get("__EVENTTARGET");
      if (!string.IsNullOrEmpty(ctrlname))
      {
        control = this.FindControl(ctrlname);
      }
      else
      {
        foreach (string ctl in this.Request.Form)
        {
          Control c = this.FindControl(ctl);
          if (c is Button)
          {
            control = c;
            break;
          }
        }
      }
      return control;
    }
    #endregion
  }
}
